/**
 * @Project RSLsXWG
 * @Author Tran Manh Hung
 * @Email: hungtmit@gmail.com | tmh@xwebgate.com
 * @Copyright © 2011 TMH. All rights reserved
 * @Createdate May 2, 2011
 * @Createtime 10:42:49 AM
 */

package com.gigalaxy.game.card
{
	import com.gigalaxy.game.card.events.CardEvent;

	import flash.events.EventDispatcher;
	import flash.events.IEventDispatcher;

	public class Card extends EventDispatcher implements IEventDispatcher
	{
		public static const CLUBS:String = "♣"; // 1
		public static const DIAMONDS:String = "♦"; // 2
		public static const HEARTS:String = "♥"; // 3
		public static const SPADES:String = "♠"; // 4

		public static const ACE:String = "A"; // 1
		public static const JACK:String = "J"; // 11
		public static const KING:String = "K"; // 13
		public static const QUEEN:String = "Q"; // 12

		private var _rank:int;

		/**
		 * Tên: spades (♠), hearts (♥), diamonds (♦), clubs (♣)<br />
		 * Giá trị: 4, 3, 2, 1<br>
		 * Giá trị của suit card không thay đổi trong tất cả các kiểu đánh bài
		 */
		private var _suit:String;

		/**
		 * rank of suit<br />
		 * <b>EG:</b><br />
		 * in "Ba cây" order of suit rank is ♦ > ♥ > ♣ > ♠<br />
		 * in "Tiến lên" order of suit rank is ♥ > ♦ > ♣ > ♠<br />
		 * in "Poker" rank of all suits are equal<br />
		 */
		private var _suitRank:int;

		/**
		 * Tên: A(ce), 2, 3, 4, 5, 6, 7, 8, 9, 10, J(ack), Q(ueen), K(ing)<br />
		 * Giá trị: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13<br/>
		 * Giá trị của card là không thay đổi trong tất cả các kiểu đánh bài<br />
		 */
		private var _value:String;

		/**
		 * order in deck | from light to heavy (small to big)...<br />
		 * use for shuffle deck<br />
		 */
		private var _weight:Number;

		private static var ACE_RANK:int = 1;
		private static var TWO_RANK:int = 2;
		private static var THREE_RANK:int = 3;
		private static var FOUR_RANK:int = 4;
		private static var FIVE_RANK:int = 5;
		private static var SIX_RANK:int = 6;
		private static var SEVEN_RANK:int = 7;
		private static var EIGHT_RANK:int = 8;
		private static var NINE_RANK:int = 9;
		private static var TEN_RANK:int = 10;
		private static var JACK_RANK:int = 11;
		private static var QUEEN_RANK:int = 12;
		private static var KING_RANK:int = 13;

		/**
		 * dùng trong hàm sort
		 */
		public var sortRank:int;

		public var isCaptured:Boolean;

		public function Card(value:String = '', suit:String = '')
		{
			resetData();

			_value = value;
			_suit = suit;
		}

		public function resetData():void
		{
			_value = '';
			_rank = 0; // same rank
			_suit = '';
			_suitRank = 0; // same rank
			_weight = 0;

			sortRank = 0; // same sort rank
			isCaptured = false;
		}

		public static function valueFromInt(value:int):String
		{
			var ret:String;

			switch (value)
			{
				case 1:
					ret = Card.ACE;
					break;
				case 2:
				case 3:
				case 4:
				case 5:
				case 6:
				case 7:
				case 8:
				case 9:
				case 10:
					ret = value.toString();
					break;
				case 11:
					ret = Card.JACK;
					break;
				case 12:
					ret = Card.QUEEN;
					break;
				case 13:
					ret = Card.KING;
					break;
				default:
					ret = "";
					break;
			}

			return ret;
		}

		public static function suitFromInt(suite:int):String
		{
			var ret:String;

			switch (suite)
			{
				case 1:
					ret += Card.CLUBS;
					break;
				case 2:
					ret += Card.DIAMONDS;
					break;
				case 3:
					ret += Card.HEARTS;
					break;
				case 4:
					ret += Card.SPADES;
					break;
				default:
					ret += "";
					break;
			}

			return ret;
		}

		/**
		 * value from 1 to 13: A 2 3 4 5 6 7 8 9 10 J Q K
		 * suit from 1 to 4: clubs diamonds hearts spades
		 */
		public function setCard(value:String = '', suit:String = ''):void
		{
			this.value = value;
			this.suit = suit;

			var e:CardEvent = new CardEvent(CardEvent.CARD_VALUE_CHANGE);
			dispatchEvent(e);
		}

		public function toStringExt(prefix:String = ""):String
		{
			var ret:String = prefix;

			switch (_value)
			{
				case Card.ACE:
					ret += "A";
					break;
				case "2":
				case "3":
				case "4":
				case "5":
				case "6":
				case "7":
				case "8":
				case "9":
				case "10":
					ret += _value.toString();
					break;
				case Card.JACK:
					ret += "J";
					break;
				case Card.QUEEN:
					ret += "Q";
					break;
				case Card.KING:
					ret += "K";
					break;
				default:
					ret += "-";
					break;
			}

			switch (_suit)
			{
				case Card.CLUBS:
					ret += "♣";
					break;
				case Card.DIAMONDS:
					ret += "♦";
					break;
				case Card.HEARTS:
					ret += "♥";
					break;
				case Card.SPADES:
					ret += "♠";
					break;
				default:
					ret += "-";
					break;
			}

			return ret;
		}

		public static function setValueRank(ace:int, two:int, three:int, four:int, five:int, six:int, seven:int, eight:int, nine:int, ten:int, jack:int, queen:int, king:int):void
		{
			ACE_RANK = ace;
			TWO_RANK = two;
			THREE_RANK = three;
			FOUR_RANK = four;
			FIVE_RANK = five;
			SIX_RANK = six;
			SEVEN_RANK = seven;
			EIGHT_RANK = eight;
			NINE_RANK = nine;
			TEN_RANK = ten;
			JACK_RANK = jack;
			QUEEN_RANK = queen;
			KING_RANK = king;
		}

		protected function rankFromValue(value:String):void
		{
			switch (value)
			{
				case Card.ACE:
					_rank = ACE_RANK;
					break;
				case "2":
					_rank = TWO_RANK;
					break;
				case "3":
					_rank = THREE_RANK;
					break;
				case "4":
					_rank = FOUR_RANK;
					break;
				case "5":
					_rank = FIVE_RANK;
					break;
				case "6":
					_rank = SIX_RANK;
					break;
				case "7":
					_rank = SEVEN_RANK;
					break;
				case "8":
					_rank = EIGHT_RANK;
					break;
				case "9":
					_rank = NINE_RANK;
					break;
				case "10":
					_rank = TEN_RANK;
					break;
				case Card.JACK:
					_rank = JACK_RANK;
					break;
				case Card.QUEEN:
					_rank = QUEEN_RANK;
					break;
				case Card.KING:
					_rank = KING_RANK;
					break;
				default:
					_rank = 0;
					break;
			}
		}

		protected function rankSuitFromSuite(suit:String):void
		{
			switch (suit)
			{
				case Card.CLUBS:
					_suitRank = 2;
					break;
				case Card.DIAMONDS:
					_suitRank = 3;
					break;
				case Card.HEARTS:
					_suitRank = 4;
					break;
				case Card.SPADES:
					_suitRank = 1;
					break;
				default:
					_suitRank = 0;
					break;
			}
		}

		public function get suit():String
		{
			return _suit;
		}

		public function set suit(value:String):void
		{
			_suit = value;

			rankSuitFromSuite(_suit);
		}

		public function get value():String
		{
			return _value;
		}

		public function set value(value:String):void
		{
			_value = value;

			rankFromValue(_value);
		}

		public function get weight():Number
		{
			return _weight;
		}

		public function set weight(value:Number):void
		{
			_weight = value;
		}

		public function get rank():int
		{
			return _rank;
		}

		/**
		 * rank of card value<br />
		 * <b>EG:</b><br />
		 * in "Ba cây" order of rank is A > 9 > 8 > 7 > 6 > 5 > 4 > 3 > 2<br />
		 * in "Tiến lên" order of rank is 2 > A > K > Q > J > 10 > 9 > 8 > 7 > 6 > 5 > 4 > 3<br />
		 * in "Phỏm" order of rank is K > Q > J > 10 > 9 > 8 > 7 > 6 > 5 > 4 > 3 > 2 > 1<br />
		 * in "Black Jack" rank of all values are equal<br />
		 */
		public function set rank(value:int):void
		{
			_rank = value;
		}

		public function get suitRank():int
		{
			return _suitRank;
		}

		public function set suitRank(value:int):void
		{
			_suitRank = value;
		}
	}
}


